Just because you can, doesn't mean you should.

Table of Contents
Complexity in Software: No Physical Constraints, No Natural Limits #
Unlike physical products, software is not bound by physical materials or manufacturing costs. This creates an illusion of limitless possibility - if you can code it, you can build it. However, without natural constraints, software projects can spiral into over-engineered architectures that are bloated, slow, and difficult to maintain.
With physical products, every additional component adds cost, weight, and risk of failure, forcing engineers to justify complexity. In software, adding more layers—microservices, event-driven architectures, AI integrations—often seems like progress but can quickly become technical debt if not managed carefully.
Many modern applications start as simple projects but quickly evolve into bloated systems due to poor planning or trends in software architecture. A startup might begin with a straightforward monolithic app but, in an effort to “scale,” prematurely adopts:
- Microservices that create unnecessary interdependencies.
- Excessive third-party integrations that increase maintenance complexity.
- Complex DevOps pipelines that slow down development instead of speeding it up.
Even more dangerous is when the initial design starts with excessive over engineering. A classic case is the overuse of microservices when they aren’t needed. While microservices make sense for massive platforms like Netflix, smaller teams often adopt them prematurely, leading to fragile systems that break apart under their own weight. Instead of simplifying, the software becomes an ecosystem of dependencies that are difficult to debug and expensive to maintain.
Why Complexity Gets a Pass in Software #
Since software complexity isn’t always obvious or when things are moving fast, chosen without enough thought, it can sneak through until it’s too late. Unlike hardware, where excessive complexity results in higher unit costs and manufacturing delays, software complexity manifests as:
- Slower development cycles.
- Unstable performance due to bloated architectures.
- Higher maintenance costs over time.
- Technical debt that forces costly rewrites.
This is why many software products launch in a functional but deeply flawed state, only to struggle with scalability and quality over time. Google Wave, for instance, was an ambitious project meant to revolutionise online communication. However, its sheer complexity made it difficult for users to adopt, and it was ultimately discontinued.
Lessons from Hardware #
Just as great hardware design values simplicity and reliability, successful software should prioritise practicality over excessive engineering. Software engineers must self-impose constraints, asking:
- Does this complexity add real value?
- Can we simplify without losing core functionality?
- Will this architecture scale without becoming a maintenance nightmare?
We rarely see physical products that match the runaway complexity of some software projects because the high costs of design, prototyping, and manufacturing usually kill them early. Most over-engineered hardware never makes it past the development stage.
However, with enough VC funding or crowdfunding hype, some manage to reach production—only to fail spectacularly when they meet real customers.
These cases below provide valuable examples of the dangers of unchecked complexity.
Juicero: Fruit Pulp Press #
The idea behind Juicero was simple: bring cold-pressed juice to the home with a sleek, high-tech juicing machine. The company raised $120 million in venture capital and spent two years developing a WiFi-enabled, app-connected juicer that squeezed pre-packaged fruit and vegetable pouches into a glass.
But despite its futuristic vision, the Juicero ended up becoming one of the most infamous examples of over-engineered hardware—and an industry-wide joke—when it was revealed that you could just squeeze the juice packs by hand without the expensive machine.
Why Did It Fail? #
- Unnecessary Complexity: The machine’s intricate design solved no real problem—a simple mechanical press (or just squeezing the pouch) worked just as well.
- Absurd Cost: Launched at $699 (later $399), plus a subscription-based juice pack model, making it an expensive gimmick.
- Artificial Constraints: The QR code system locked customers into proprietary pouches, adding complexity with no benefit.
- Misunderstood Market: Juice enthusiasts wanted freshly pressed juice, not a processed-pouch subscription service.
Juicero became a cautionary tale of over-engineering, where technology was added for the sake of it rather than improving the user experience. The same mistake happens in software—bloated architectures, unnecessary features, and overcomplicated solutions that don’t serve a real need.
Juicero shut down in 2017, illustrating that complexity without purpose is just waste.
Revoo: Hubless E-Bike #
However, while the bike achieved its aesthetic goal, the engineering required to make it work introduced crippling trade-offs that made it almost unusable in practice.
Why Did It Fail? #
The core requirement—creating hubless wheels—forced engineering constraints that made the bike worse in nearly every way:
- Weight & Efficiency Issues: Traditional bicycle hubs house the drivetrain, bearings, and other crucial mechanical components that make the bike function smoothly. Removing the hub meant reinventing core mechanical systems in an unconventional way, leading to inefficiencies, added weight, reduced performance and a very noisy drivetrain.
- Structural Weakness & Durability Problems: Hubless wheels need an external drive system and additional support structures, which reduced the bike’s stability and made it prone to mechanical failure.
- Compromised Ride Quality: Reviews highlighted how the bike’s unique wheel system made for an awkward, unstable ride. What looked cool in marketing materials ended up being impractical and uncomfortable to ride in real-world conditions.
The Lesson: When Innovation Comes at the Cost of Usability
The Revoo bike is a real-world example of how prioritising aesthetics over function can lead to disaster. While the hubless wheel concept was technically possible, the trade-offs in usability, weight, repairability, and cost made it a fundamentally bad idea.
The same kind of failure happens in software when developers chase novelty over practicality, adopting new technologies or architectural patterns just because they’re trendy, rather than because they actually improve the product.
Kuvée: WiFi Enabled Wine Bottle #
Kuvée set out to “modernise” wine drinking with a WiFi-connected “smart” wine bottle designed to keep wine fresh by preventing oxidation. Backed by $6 million in VC funding, it featured a touchscreen display, proprietary wine cartridges, and a subscription-based model.
Why Did It Fail? #
- Unnecessary Complexity: Traditional wine preservation methods (vacuum pumps, argon gas sprays) already work well. Kuvée added tech for the sake of it.
- Locked-In Ecosystem: The bottle only worked with Kuvée-branded wine cartridges, limiting consumer choice and forcing subscription purchases.
- Bulky & Unappealing Design: Instead of enhancing the experience, the oversized plastic device felt clunky compared to a simple glass bottle.
- Market Misalignment: Wine enthusiasts appreciate tradition and simplicity—a smart bottle didn’t solve a real problem for them.
Not every product needs to be smart. Kuvée’s failure highlights how forcing technology into a product doesn’t automatically make it better. The same happens in software, overcomplicating simple solutions with unnecessary AI, blockchain, or microservices.
Kuvée shut down in 2019, proving that tech should enhance a product, not burden it.
Complexity is a Silent Killer, But Hardware and Software Fail Differently #
In hardware, excessive complexity usually kills products before they even reach production. The costs of design, prototyping, and manufacturing act as natural constraints—forcing companies to prioritise simplicity, reliability, and cost-effectiveness. When budgets are tight, complexity is naturally weeded out.
However, big budgets can override these constraints, allowing over-engineered products to make it to market—only to fail when they meet real-world customers. Juicero, Revoo, and Kuvée all raised millions, pushing forward with flawed concepts that were too complex, too expensive, or simply unnecessary. In the end, the very complexity that got them built led to their downfall.
In software, the story is different. Because software isn’t constrained by physical materials, excessive complexity can be introduced early—and hidden for a long time. Bloated architectures, unnecessary abstractions, and over-engineered solutions might not stop a product from launching. In fact, a software product can seem successful at first, only for its hidden complexity to emerge over time—leading to slow ongoing development, fragile systems, and technical debt that eventually grinds progress to a halt.
Simplicity Wins #
The difference between hardware and software failure is when the complexity becomes a problem:
In hardware, complexity often kills a product before launch, unless deep pockets delay the inevitable. In software, complexity can be ignored at first, only to surface later when it becomes a drag on progress. The best products, whether hardware or software, embrace constraints and focus on solving real problems, not just showcasing technology for its own sake.
The next time you’re designing a product, ask yourself:
- Is this complexity solving a real problem?
- Would a simpler approach achieve the same result?
- Are we adding tech because it’s needed — or just because we can (or it’s the latest shiny thing)?
The best solutions are often the simplest ones. If complexity is needed, ensure it’s absolutely necessary, otherwise it will come back to bite you.